/**
 * Student Name: Thong, Wang Kit Wilson (50419704)
 *               Yin, Xing (51590277)
 */
#include "SqlLog.h"
#include "Log.h"
#include <stdlib.h>
#include <stdio.h>

ReturnType_t 
LogEnqueueMessage (sqlite3* db, int studentId, WriteCommandType_t comm, void* arg, int argsSize)
{
	FUNC_LOG ();

	ReturnType_t ret = 0;
	sqlite3_stmt* stmt = 0;

	const char* sql = "insert into MessageLog (studentId, commandType, argValue) values (?, ?, ?);";
	if (sqlite3_prepare_v2 (db, sql, -1, &stmt, NULL) != SQLITE_OK) {
		ERR_LOG (sqlite3_errmsg (db));	
		ret = BAD_TECHNICAL_PROBLEM;
	}

	if (ret == 0) {
		if (sqlite3_bind_int (stmt, 1, studentId) != SQLITE_OK) {
			ERR_LOG (sqlite3_errmsg (db));
			ret = BAD_TECHNICAL_PROBLEM;
		}
	}
	if (ret == 0) {
		if (sqlite3_bind_int  (stmt, 2, comm) != SQLITE_OK) {
			ERR_LOG (sqlite3_errmsg (db));
			ret = BAD_TECHNICAL_PROBLEM;
		}
	}
	if (ret == 0) {
		if (sqlite3_bind_blob (stmt, 3, (void*)arg, argsSize, SQLITE_TRANSIENT) != SQLITE_OK) {
			ERR_LOG (sqlite3_errmsg (db));
			ret = BAD_TECHNICAL_PROBLEM;
		}
	}

	if (ret == 0) {
		if (sqlite3_step (stmt) != SQLITE_DONE) {
			ERR_LOG (sqlite3_errmsg (db));
			ret = BAD_TECHNICAL_PROBLEM;
		}
	}

	if (sqlite3_finalize (stmt) != SQLITE_OK) {
		ERR_LOG (sqlite3_errmsg (db));
		ret = BAD_TECHNICAL_PROBLEM;
	}

	if (ret == 0) {
		ret = OK_BOOK_COURT_SYS;
		DEBUG_LOG ("return = OK_BOOK_COURT_SYS");
	}

	return ret;
}

ReturnType_t 
LogReadHeadMessage (sqlite3* db, int studentId, WriteCommandType_t* comm, void** arg)
{
	FUNC_LOG ();

	ReturnType_t ret = 0;
	sqlite3_stmt* stmt = 0;
	char buf[100];
	
	const char* sql = "select argValue, commandType from MessageLog order by Id limit 1;";
	if (sqlite3_prepare (db, sql, -1, &stmt, NULL) != SQLITE_OK) {
		ERR_LOG (sqlite3_errmsg (db));
		ret = BAD_TECHNICAL_PROBLEM;
	}

	//if (ret == 0) {
	//	if (sqlite3_bind_int (stmt, 1, studentId) != SQLITE_OK) {
	//		ERR_LOG (sqlite3_errmsg (db));
	//		ret = BAD_TECHNICAL_PROBLEM;
	//	}
	//}

	if (ret == 0) {
		int sqlite_ret = sqlite3_step (stmt);
		if (sqlite_ret != SQLITE_ROW && sqlite_ret != SQLITE_DONE) {
			ERR_LOG (sqlite3_errmsg (db));
			ret = BAD_TECHNICAL_PROBLEM;
		}
		if (sqlite_ret == SQLITE_ROW) {
			// get the blob
			const void* blob = sqlite3_column_blob (stmt, 0);
			int blobBytes = sqlite3_column_bytes (stmt, 0);
			*arg = malloc (blobBytes);
			memcpy (*arg, blob, blobBytes);
			DEBUG_LOG ("memcpy() returned");
			// get the command type
			*comm = (WriteCommandType_t)sqlite3_column_int (stmt, 1);
			DEBUG_LOG ("sqlite3_column_int() returned");
			ret = OK_BOOK_COURT_SYS;
			DEBUG_LOG ("return = OK_BOOK_COURT_SYS");
		} else if (sqlite_ret == SQLITE_DONE) {
			ERR_LOG ("return = BAD_MESSAGE_LOG_NOT_FOUND");
			ret = BAD_MESSAGE_LOG_NOT_FOUND;
		}
	}

	if (sqlite3_finalize (stmt) != SQLITE_OK) {
		ERR_LOG (sqlite3_errmsg (db));
		ret = BAD_TECHNICAL_PROBLEM;
	}

	return ret;
}

ReturnType_t 
LogDequeueMessage (sqlite3* db, int studentId)
{
	FUNC_LOG ();

	ReturnType_t ret = 0;
	char** result;
	int rows, cols;
	char* errmsg;
	int dequeueId;

	char* sql = sqlite3_mprintf ("select Id from MessageLog order by Id;");
	if (sqlite3_get_table (db, sql, &result, &rows, &cols, &errmsg) != SQLITE_OK) {
		ERR_LOG (errmsg);
		sqlite3_free (errmsg);
		ret = BAD_TECHNICAL_PROBLEM;
	}
	sqlite3_free (sql);

	if (rows == 0) {
		ret = BAD_MESSAGE_LOG_NOT_FOUND;
		WARN_LOG ("return = BAD_MESSAGE_LOG_NOT_FOUND");
	} else if (rows < 0) {
		ERR_LOG ("Unexpected error!");
		exit (1);
	}
	if (ret == 0)
		dequeueId = atoi (result[1]);

	sqlite3_free_table (result);

	if (ret == 0) {			
		sql = sqlite3_mprintf ("delete from MessageLog where id = %d;", dequeueId);
		if (sqlite3_exec (db, sql, NULL,NULL, &errmsg) != SQLITE_OK) {
			ERR_LOG (errmsg);
			sqlite3_free (errmsg);
			ret = BAD_TECHNICAL_PROBLEM;
		}
		sqlite3_free (sql);
	}

	if (ret == 0) {
		ret = OK_BOOK_COURT_SYS;
		DEBUG_LOG ("return = OK_BOOK_COURT_SYS");
	}

	return ret;
}
